/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-11-14     ganze       the first version
 */
#ifndef APPLICATIONS_BMI270_SENSOR_BMI270_H_
#define APPLICATIONS_BMI270_SENSOR_BMI270_H_

#include <rtthread_nano_device.h>
#include <rtthread.h>
#include <sensor_common.h>

#define INT_SPI 0
#define INT_I2C 1

#define BMI270_SPI_BUSNAME "spi1"
#define BMI270_SPI_DEVNAME "spi16"

#define BMI270_DEVICE_NAME "bmi270"

#define BMI270_ACCE_DEV_NAME "bmi270_acce"
#define BMI270_GYRO_DEV_NAME "bmi270_gyro"

/* 根据数据手册，I2C作为接口时，当SDO引脚接到GND则为默认的I2C地址0x68
    当SDO引脚接到VDDIO则I2C地址是0x69，根据实际情况选择
 */
#define BMI270_I2C_ADDR 0x68

#define BMI270_USING_ACCE /* 使用加速度 */
#define BMI270_USING_GYRO /* 使用陀螺仪 */

#define FIFO_HAS_HEAD (0x10 << 8)
#define FIFO_HAS_AUX (0x20 << 8)
#define FIFO_HAS_ACCE (0x40 << 8)
#define FIFO_HAS_GYRO (0x80 << 8)

#define BMI270_ACCE_MAX_RANGE 16000     /* BMI270加速度最大量程16g */
#define BMI270_ACCE_MIN_RANGE 2000      /* BMI270加速度最大量程2g */
#define BMI270_ACCE_MIN_PERIOD_MS_RT 10 /* BMI270加速度测量最短时间 */
#define BMI270_ACCE_FIFO_BUF_MIN 8      /* BMI270从FIFO获取加速度测量得到数据，缓存加速度数据的最小长度，考虑到有6个字节存储加速度3轴，这里选8 */

#define BMI270_GYRO_MAX_RANGE 2000000   /* BMI270陀螺仪最大量程2000dps */
#define BMI270_GYRO_MIN_RANGE 125000    /* BMI270陀螺仪最小量程125dps */
#define BMI270_GYRO_MIN_PERIOD_MS_RT 10 /* BMI270陀螺仪测量最短时间 */
#define BMI270_GYRO_FIFO_BUF_MIN 8      /* BMI270从FIFO获取加速度测量得到数据，缓存加速度数据的最小长度，考虑到有6个字节存储加速度3轴，这里选8 */

#define BMI270_RX_INT_PIN BMI2_INT1        /* 此处设置RX接收中断引脚为INT1 */
#define BMI270_FIFO_FULL_INT_PIN BMI2_INT2 /* 此处设置FIFO满中断引脚为INT1 */
#define BMI270_INT_PIN_ACTIVE_HIGH 1       /* INT脚中断时是高电平 */
#define BMI270_INT_PIN_ACTIVE_LOW 0        /* INT脚中断时是低电平 */

#define BMI270_ACCE_2G_RESOLUTION 16384
#define BMI270_ACCE_4G_RESOLUTION 8192
#define BMI270_ACCE_8G_RESOLUTION 4096
#define BMI270_ACCE_16G_RESOLUTION 2048

#define BMI270_GYRO_125DPS_RESOLUTION 262.144f
#define BMI270_GYRO_250DPS_RESOLUTION 131.072f
#define BMI270_GYRO_500DPS_RESOLUTION 65.536f
#define BMI270_GYRO_1000DPS_RESOLUTION 32.768f
#define BMI270_GYRO_2000DPS_RESOLUTION 16.384f

/* CMD */
#define BMI270_CMD_SET_ODR 1
#define BMI270_CMD_SET_PWR_MODE 2
#define BMI270_CMD_SET_RANGE 3
#define BMI270_SELF_TEST 4

/* POWER MODE */
#define BMI270_POWER_DOWN 0
#define BMI270_POWER_NORMAL 1
#define BMI270_POWER_LOW 2

// BSP definition
#define BMI270_USING_SPI

#ifdef BMI270_USING_SPI

#define BMI270_SPI SPI1

#define BMI270_SPI_SCK_GPIO GPIOA
#define BMI270_SPI_SCK_PIN GPIO_PIN_5
#define BMI270_SPI_SCK_AF GPIO_AF5_SPI1

#define BMI270_SPI_MOSI_GPIO GPIOA
#define BMI270_SPI_MOSI_PIN GPIO_PIN_7
#define BMI270_SPI_MOSI_AF GPIO_AF5_SPI1

#define BMI270_SPI_MISO_GPIO GPIOA
#define BMI270_SPI_MISO_PIN GPIO_PIN_6
#define BMI270_SPI_MISO_AF GPIO_AF5_SPI1

#define BMI270_SPI_CS_GPIO GPIOA
#define BMI270_SPI_CS_PIN GPIO_PIN_4

#define BMI270_SPI_SCK_GPIO_RCC_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define BMI270_SPI_MISO_GPIO_RCC_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define BMI270_SPI_MOSI_GPIO_RCC_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define BMI270_SPI_CS_GPIO_RCC_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()

#define BMI270_SPI_RCC_ENABLE() __HAL_RCC_SPI1_CLK_ENABLE()

#else

#define BMI270_I2C I2C1
#define BMI270_I2C_SCL_GPIO GPIOA
#define BMI270_I2C_SCL_PIN GPIO_PIN_0
#define BMI270_I2C_SCL_AF GPIO_AF4_I2C1

#define BMI270_I2C_SDA_GPIO GPIOA
#define BMI270_I2C_SDA_PIN GPIO_PIN_0
#define BMI270_I2C_SDA_AF GPIO_AF4_I2C1

#define BMI270_I2C_SCL_GPIO_RCC_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define BMI270_I2C_SDA_GPIO_RCC_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()

#define BMI270_I2C_RCC_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()

#define BMI270_I2C_ADDR BMI270_I2C_ADDR_PRIM

#endif

typedef struct Bmi270_Imu_Data
{
    float x;
    float y;
    float z;
} bmi270_imu_data;

int rt_bmi270_sensor_register(void);

#endif /* APPLICATIONS_BMI270_SENSOR_BMI270_H_ */
